;   This program is free software: you can redistribute it and/or modify
;   it under the terms of the GNU General Public License as published by
;   the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.
;
;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.
;
;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
;	
;	Copywrite Sean Haas 2011-12
ORG 100h

JMP SHORT Init
Init:
	cli
	mov ax,0
	mov ss,ax
	mov sp,0FFFFh
	sti

	mov si,splash
	call print

	mov si,loada20
	call print
	call a20on

	mov si,loadmem
	call print
	mov si,0
	mov dx,99h
	call memclear

	mov si,void + 15
	mov dx,void + 512
	call memclear

	mov si,vrtmem
	call print
	mov si,void
	mov di,void + 512
	call topage
	
	mov si,loadstack
	call print
	mov [sp0],sp
	mov [sp1],sp
	add byte[sp1],12

	mov si,loadmulti
	call print
	mov ax,0
	call multi	

	call newfat

        mov si,loading
        call print

	mov dx,5
        call dotdot
	call beep
        call clear

        mov si,header
        call print

	mov si,ips
	call print
	call getips
	mov ax,bx
	call tostring
	mov si,ax
	call print
	mov si,ipsticks
	call print

	mov si,voidat
	call print
	mov ax,void
	call tostring
	mov si,ax
	call print
	mov si,return
	call print
main:			;Main command loop
        mov si,prompt
        call print

	hlt

        mov di,buffer
        call input

	mov di,buffer
	call commands
jmp main

commands:		;Command interpreter
	mov si,help	;IN - di, string to interpret
	call compare
	jc .helpcmd

	mov si,reboot
	call compare
	jc .rebootcmd

	mov si,time
	call compare
	jc .timecmd

        mov si,info
        call compare
        jc .infocmd

        mov si,off
        call compare
        jc .offcmd

        mov si,login
        call compare
        jc .login

        mov si,cls
        call compare
        jc .clear

        mov si,mouse
        call compare
        jc .mousecmd

        mov si,dump
        call compare
        jc .dumpcmd

        mov si,crypt
        call compare
        jc .cryptcmd

	mov si,crash
	call compare
	jc .crashcmd

	mov si,swap
	call compare
	jc .swapcmd

	mov si,mem
	call compare
	jc .memcmd

	mov si,regs
	call compare
	jc .regscmd

	mov si,lang
	call compare
	jc .langcmd

	mov si,task
	call compare
	jc .taskcmd

	mov si,catch
	call compare
	jc .catchcmd

	mov si,loopy
	call compare
	jc .loopcmd

	mov si,date
	call compare
	jc .datecmd
	
	mov si,wind
	call compare
	jc .windcmd

	mov si,aloc
	call compare
	jc .aloccmd

	mov si,empt
	call compare
	jc .emptcmd

	mov si,stack
	call compare
	jc .stackcmd

	mov si,vrtp
	call compare
	jc .vrtpcmd

	mov si,file
	call compare
	jc .filecmd
	
        mov si,error
        call print
	
        jmp .done

.helpcmd
        mov si,helpstring
        call print
        jmp .done
.rebootcmd
	call reboot1
	jmp .done
.timecmd
	call gettime
	jmp .done
.infocmd
        mov si,infomsg
        call print
	call sysinfo
        jmp .done
.offcmd
        call cpuoff
.login
        call login1
        jmp .done
.clear
        call clear
        jmp .done
.mousecmd
        call mousetest
        jmp .done
.dumpcmd
        mov si,0
        call memdump
        jmp .done
.cryptcmd
        call crypto
        jmp .done
.crashcmd
	call bsod
	jmp .done
.swapcmd
	call swapit
	jmp .done
.memcmd
	call getmem
	jmp .done
.regscmd
	call getregs
	jmp .done
.langcmd
	call dreklang
	jmp .done
.taskcmd
	call taskman
	jmp .done
.catchcmd
	call catchfire
	jmp .done
.loopcmd
	call loopit
	jmp .done
.datecmd
	call getdate
	jmp .done
.windcmd
	call startwind
	jmp .done
.aloccmd
	call memaloc
	jmp .done
.emptcmd
	call freemem
	jmp .done
.stackcmd
	call printstack
	jmp .done
.vrtpcmd
	call loadpage
	jmp .done
.filecmd
	call fileman
	jmp .done
.done
ret

	sp0 db 0
	sp1 db 0
        loading db 13,10,'Loading',0
	loada20 db 'Setting Up a20..',13,10,0
	loadmem db 'Setting Up Memory Allocater...',13,10,0
	loadmulti db 'Setting Up Multi-Threading...',13,10,0
	loadstack db 'Setting Up Stack...',13,10,0
	loadgood db 'Making Pretty...',13,10,0
	vrtmem db 'Setting up virtuall memory...',13,10,0
        dot db '.',0
	voidat db 13,10,'Void at ',0
	ips db '1m instructions in ',0
	ipsticks db ' ticks',0
	file db 'file',0
        help db 'help',0
        header db ' ____',13,10,'| 00_|_ DreckigOS',13,10,'| 0| 0 | v0.005 Alpha',13,10,'|__|___| 2011-12 Sean Haas',13,10,0
        prompt db 13,10,'?>',0
        error db 13,10,'Error!',13,10,0
        helpstring db 13,10,'DreckigOS Help',13,10,'help - print help message',13,10,'stack - print stack',13,10,'catch - HCF busy idle',13,10,'aloc - allocate memory',13,10,'empt - free memory',13,10,'regs - print registers',13,10,'mem - display memory in kbs',13,10,'swap - switch between tasks',13,10,'crash - guess...',13,10,'mouse - mouse test',13,10,'clear - clear screen',13,10,'login - security manager',13,10,'info - show Dreckig info',13,10,'time - print time',13,10,'date - print date',13,10,'algs - command line calculator',13,10,'wind - graphical user interface',13,10,'crypt - encrypt text',13,10,'reboot - reboot computer',13,10,0
        reboot db 'reboot',0
	rebootmsg db 13,10,'Rebooting...',0
	stack db 'stack',0
	vrtp db 'vrtp',0
	algs db 'algs',0
	algsmsg db 13,10,'ALGS command line calculator',13,10,0
	algsprmpt db 'ALGS>',0
	date db 'date',0
	catch db 'catch',0
	regs db 'regs',0
	wind db 'wind',0
	empt db 'empt',0
	aloc db 'aloc',0
        crypt db 'crypt',0
        cryptmsg db 'CRYPT encription manager',13,10,0
	en db 'en',0
	de db 'de',0
	lang db 'lang',0
	langprmpt db 'LANG>',0
	langmsg db 'LANG Dreckig language interpreter',13,10,0
        cryptprmpt db 'CRYPT>',0
	ins db 'Input>',0
	key db 'Key>',0
	quit db 'quit',0
	time db 'time',0
        info db 'info',0
        infomsg db 13,10,'DreckigOS v0.005',13,10,'Copywrite 2011-12 Sean Haas',13,10,'For x86 PC and compatibles',13,10,0
        off db 'off',0
        offmsg db 13,10,'Computer Halted...',0
        login db 'login',0
        root db 'root',0
        rootpas db 'toor',0
        loginmsg db 13,10,'LOGIN security manager',13,10,0
        user db 'USER>',0
        pass db 'PASS>',0
        cls db 'clear',0
        mouse db 'mouse',0
        dump db 'dump',0
	crash db 'crash',0
	bsodmsg db 13,10,13,10,'          Dreckig has encountered an error',13,10,'          The only way out now is a hard reboot',13,10,'               :-(',13,10,0
	draw db 'draw',0
	drawmsg db 'DRAW drawing manager',13,10,0
	drawprmpt db 'DRAW>',0
	task db 'task',0
	swap db 'swap',0
	loopy db 'loop',0
	mem db 'mem',0
	kbs db 'kb',13,10,0 
	num1in db 'First>',0
	num2in db 'Second>',0
	sum db 'sum',0
	dif db 'dif',0
	pp db 'pp',0
	mm db 'mm',0
	eql db 'eql',0
	return db '',13,10,0
	true db 'true',0
	false db 'false',0
	kb db 'kb',13,10,0
	u db 'u',0
	d db 'd',0
	l db 'l',0
	r db 'r',0
        press db 13,10,'Press any key to continue...',13,10,0
	page dw 0
        start db 0
        buffer times 64 db 0
        tmpbuf dw 0
	num1 db 0
	num2 db 0 
	tmpx dw 0
	tmpy dw 0

%INCLUDE "lang.asm"
%INCLUDE "task.asm"
%INCLUDE "memc.asm"
%INCLUDE "wind.asm"	
%INCLUDE "splash.asm"
%INCLUDE "test.asm"
%INCLUDE "icons.asm"
%INCLUDE "bFAT.asm"

print:			;Print string
        mov ah,0Eh	;IN - si, string to print
	mov bl,2
.repeat
        lodsb
        cmp al,0
        je .done
        int 10h
        jmp .repeat
.done
        ret

dotdot:
	mov cx,0	;Print dots to the screen with a time delay
.loop			;IN - dx, number of dots
        add cx,1
        mov si,dot
        call print
        mov ax,1
        call pause1
        cmp cx,dx
        je .done
        jmp .loop
.done
        ret

input:			;Take keyboard input
        xor cl,cl	;IN - di, string to store input in
.loop
        mov ah,0
        int 0x16

        cmp al,0x0D
        je .done

        mov ah,0x0E
        int 10h

        stosb
        inc cl
        jmp .loop
.done
        mov al,0
        stosb

        mov ah,0x0E
        mov al,0x0D
        int 0x10
        mov al,0x0A
        int 0x10
ret

printret:
	pusha
	mov si,return
	call print
	popa
ret

waitkey:		;Wait for key press
	pusha		;OUT - ax, key pressed
	mov ax,0
	mov ah,10h
	int 16h
	mov [.tmp],ax
	popa
	mov ax,[.tmp]
ret
	.tmp dw 0

compare:		;Compare two strings
        pusha		;IN di, si, strings to compare
.loop			;OUT - setc carry flag if strings are equal
        mov al,[si]
        mov bl,[di]
        cmp al,bl
        jne .no

        cmp al,0
        je .done

        inc si
        inc di
        jmp .loop
.no
        popa
        clc
        ret
.done
        popa
        stc
	ret

clear:			;Clear screen
        pusha
        mov dx,0
        pusha
        mov bh,0
        mov ah,2
        int 10h
        popa

        mov ah,6
        mov al,0
        mov bh,2
        mov cx,0
        mov dh,24
        mov dl,79
        int 10h
        popa
ret

pause1:			;Time delay
        pusha		;IN - ax, time in tenths of a second
        mov bx,ax
        mov cx,1h
        mov dx,86A0h
        mov ax,0
        mov ah,86h
.loop
        int 15h
        dec bx
        jne .loop
        popa
ret

beep:			;Beep
	mov si,.beep
	call print
ret
	.beep db 7,0

trunc:			;Truncate string
	pusha		;IN - si, string in, ax, size

	add si, ax
	mov byte [si], 0

	popa
	ret

login1:
        mov si,loginmsg
        call print
.loop
        mov si,user
        call print

        mov di,buffer
        call input

        mov di,buffer
        mov si,root
        call compare
        jc .root

        mov si,error
        call print
        jmp .loop
.root
        mov si,pass
        call print

        mov di,buffer
        call input

        mov di,buffer
        mov si,rootpas
        call compare
        jc .ok
        
        jmp .loop
.ok
ret

mousetest:
	mov ah,0xC2
	mov al,00h
	mov bh,01h
	int 15h
	
	cmp ah,0
	jg .err
	jmp .done
.err
	mov si,error
	call print
.done
ret

length:			;Get string length
        pusha		;IN - ax, string
        mov bx,ax	;OUT - ax, length
        mov cx,0
.loop
        cmp byte [bx],0
        je .done
        inc bx
        inc cx
        jmp .loop
.done
        mov word [.tmp],cx
        popa
        mov ax,[.tmp]
ret
        .tmp dw 0

bcdtoint:			;Convert BCD to int
	pusha			;IN - al, BCD 
	mov bl,al		;OUT - ax, int
	add ax,0Fh
	mov cx,ax
	shr bl,4
	mov al,10
	mul bl
	
	add ax,cx
	mov [.tmp],ax
	popa
	mov ax,[.tmp]
ret
	.tmp dw 0

toint:
        pusha
	mov ax, si			
	call length

	add si, ax		
	dec si

	mov cx, ax		

	mov bx, 0		
	mov ax, 0

	mov word [.multiplier], 1	
.loop:
	mov ax, 0
	mov byte al, [si]		
	sub al, 48			

	mul word [.multiplier]		

	add bx, ax			

	push ax				
	mov word ax, [.multiplier]
	mov dx, 10
	mul dx
	mov word [.multiplier], ax
	pop ax

	dec cx				
	cmp cx, 0
	je .finish
	dec si				
	jmp .loop
.finish:
	mov word [.tmp], bx
	popa
	mov word ax, [.tmp]

	ret

	.multiplier	dw 0
	.tmp		dw 0

tostring:
        pusha
        mov cx,0
        mov bx,10
        mov di,.t
.push
        mov dx,0
        div bx
        inc cx
        push dx
        test ax,ax
        jnz .push
.pop
        pop dx
        add dl,'0'
        mov [di],dl
	inc di
        dec cx
        jnz .pop

        mov byte [di],0
        popa
        mov ax,.t
ret
        .t times 7 db 0

move:
	pusha
	mov bh,0
	mov ah,2
	int 10h
	popa
ret

back:
	pusha
	mov bh,0
	mov ah,3
	int 10h

	mov [.tmp],dx
	popa
	mov dx,[.tmp]
ret
	.tmp dw 0

memdump:
	mov si,.bott
	call print
	mov di,buffer
	call input
	
	mov si,buffer
	call toint
	mov si,ax
	call getdump
ret
	.bott db 'Bottom>',0

crypto:
	mov si,cryptmsg
	call print
	mov bx,0
.loop
	cmp bx,1
	je .done

	mov si,cryptprmpt
	call print
	mov di,buffer
	call input

	mov di,buffer
	mov si,quit
	call compare
	jc .quit

	mov di,buffer
	mov si,en
	call compare
	jc .encmd

	mov di,buffer
	mov si,de
	call compare
	jc .encmd

jmp .loop

.encmd
	mov si,key
	call print
	mov di,buffer	
	call input
	mov cl,buffer
	
        mov si,ins
	call print
	mov di,buffer
	call input
	
	mov si,buffer
        mov ah,0Eh
.enloop
	lodsb
	xor al,cl
	stosb
	int 10h
loop .enloop
	mov si,return
	call print
jmp .loop

.quit
	mov bx,1
	jmp .done
jmp .loop
.done
ret	

findchar:
	pusha
	mov cx,1
.more
	cmp byte [si],al
	je .done
	cmp byte [si],0
	je .no
	inc si
	inc cx
	jmp .more
.done
	mov [.tmp],cx
	popa
	mov ax,[.tmp]
	ret
.no
	popa
	mov ax,0
ret
	.tmp db 0

catchfire:
	mov si,.hcfprmpt
	call print
	mov di,buffer
	call input
	mov si,buffer
	call toint
	mov bx,ax
	call HCF
ret
	.hcfprmpt db 'Length>',0

sysinfo:
	int 11h
	mov si,ax
	call tostring
	mov si,ax
	call print
ret

gettime:
	mov ax,0
	mov al,4h		;Hour
	out 70h,al
	in al,71h
	call bcdtoint
	call tostring
	mov si,ax
	call print
	mov si,.space
	call print
	
	mov ax,0
	mov al,2h		;Minute
	out 70h,al
	in al,71h
	call bcdtoint
	call tostring
	mov si,ax
	call print
	mov si,.space
	call print

	mov ax,0		;Second
	mov al,0
	out 70h,al
	in al,71h
	call bcdtoint
	call tostring
	mov si,ax
	call print

	mov si,return
	call print
ret
	.space db ':',0

getdate:
	mov ax,0		;Day
	mov al,7h
	out 70h,al
	in al,71h
	call bcdtoint
	call tostring
	mov si,ax
	call print
	mov si,.space
	call print
		
	mov ax,0		;Month
	mov al,8h
	out 70h,al
	in al,71h
	call bcdtoint
	call tostring
	mov si,ax
	call print
	mov si,.space
	call print

	mov ax,0		;Year
	mov al,9h
	out 70h,al
	in al,71h
	call bcdtoint
	call tostring
	mov si,ax
	call print
	mov si,return
	call print
ret
	.space db ',',0

getdump:
	mov bx,0
.repeat
	mov ah,0Eh
        lodsb
        cmp bx,512
        je .done
        int 10h
        add bx,1
        cmp cx,5
        je .done
        jmp .repeat
.done	
ret

getmem:
	pusha
	mov si,return
	call print
	mov al,18h
	out 70h,al
	in al,71h
	mov ah,al
	mov al,17h
	out 70h,al
	in al,71h
	add ax,1024
	call tostring
	mov si,ax
	call print
	mov si,kbs
	call print
	popa
ret

getips:
	cli
	mov al,00000000b
	out 43h,al
	in al,40h	
	mov ah,al
	in al,40h
	rol ax,8
	sti
	push ax
	mov ax,0
.loop
	cmp ax,9C4h
	jge .done
	add ax,1
	mov bx,ax
	mov bx,ax
	mov bx,ax
	mov bx,ax
jmp .loop
.done
	cli
	mov al,00000000b
	out 43h,al
	in al,40h	
	mov ah,al
	in al,40h
	rol ax,8
	sti
	mov bx,ax
	pop ax
	sub ax,bx
	mov bx,ax
ret

getregs:
	push si
	
	mov si,.ax
	call print
	call tostring
	mov si,ax
	call print

	mov si,.bx
	call print
	mov ax,bx
	call tostring
	mov si,ax
	call print

	mov si,.cx
	call print
	mov ax,cx
	call tostring
	mov si,ax
	call print

	mov si,.dx
	call print
	mov ax,dx
	call tostring
	mov si,ax
	call print
	mov si,return
	call print

	mov si,.si
	call print
	pop si
	mov ax,si
	call tostring
	mov si,ax
	call print

	mov si,.di
	call print
	mov ax,di
	call tostring
	mov si,ax
	call print

	mov si,.sp
	call print
	mov ax,sp
	call tostring
	mov si,ax
	call print

	mov si,.bp
	call print
	mov ax,bp
	call tostring
	mov si,ax
	call print
	mov si,return
	call print

	mov si,.cs
	call print
	mov ax,cs
	call tostring
	mov si,ax
	call print

	mov si,.ds
	call print
	mov ax,ds
	call tostring
	mov si,ax
	call print

	mov si,.ss
	call print
	mov ax,ss
	call tostring
	mov si,ax
	call print
	
	mov si,.es
	call print
	mov ax,es
	call tostring
	mov si,ax
	call print
	mov si,return
	call print	
ret
	.ax db '     ax ',0
	.bx db '     bx ',0
	.cx db '     cx ',0
	.dx db '     dx ',0
	.si db '     si ',0
	.di db '     di ',0
	.sp db '     sp ',0
	.bp db '     dp ',0
	.cs db '     cs ',0
	.ds db '     ds ',0
	.ss db '     ss ',0
	.es db '     es ',0

swapit:
	mov ax,[page]
	cmp ax,0
	je .two
	
	mov ax,0
	call multi
	mov ah,05h
	mov al,0
	int 10h
	mov ax,0
	jmp .done
	
.two
	mov ax,1
	call multi
	mov ah,05h
	mov al,1
	int 10h
	mov ax,1
	
	.done
	mov [page],ax
ret

multi:
	cmp ax,0
	je .cpu0

	cmp ax,1
	je .cpu1
	
.cpu0
	mov ax,0	
	;call swapstack
	
	mov [.ax1],ax
	mov [.bx1],bx
	mov [.cx1],cx
	mov [.dx1],dx

	mov ax,[.ax0]
	mov bx,[.bx0]
	mov cx,[.cx0]	
	mov dx,[.dx0]
jmp .done

.cpu1
	mov ax,1
	;call swapstack
	
	mov [.ax0],ax
	mov [.bx0],bx
	mov [.cx0],cx
	mov [.dx0],dx	

	mov ax,[.ax1]
	mov bx,[.bx1]
	mov cx,[.cx1]	
	mov dx,[.dx1]
jmp .done

.done
ret
	.ax0 dw 0
	.bx0 dw 0
	.cx0 dw 0
	.dx0 dw 0
	.ax1 dw 0
	.bx1 dw 0
	.cx1 dw 0
	.dx1 dw 0

taskman:
	call gotask
ret

loopit:
	mov si,.prmpt
	call print
	mov di,buffer
	call input
.loop
	mov di,buffer
	call commands
	mov al,0
	mov ah,01h
	int 16h
	cmp al,13
	jg .done	
jmp .loop
.done
ret
	.prmpt db 'LOOP>',0

bsod:
	mov dx,0
	mov bh,0
	mov ah,2h
	int 10h
	mov cx,2000
	mov bh,0
	mov bl,17h
	mov al,20h
	mov ah,9h
	int 10h

	mov si,bsodmsg
	call print
	call getregs
	call cpuoff
ret

reboot1:
	mov si,rebootmsg
	call print
	mov dx,5
        call dotdot
	call clear
        mov ax,0
        int 0x19

cpuoff:
        mov si,offmsg
        call print
.loop
	hlt
	jmp .loop
	jmp $

kernend db 13,10,'Dreckig Kernel End',13,10,0
void db 0,0,'Void Start',0,0	
	times 64 db 0